package com.demo.scenic.service.impl;

import com.demo.scenic.common.BaseResponse;
import com.demo.scenic.domain.*;
import com.demo.scenic.domain.vo.*;
import com.demo.scenic.mapper.*;
import com.demo.scenic.service.CustomerService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;

import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CustomerServiceImpl implements CustomerService {
    private final ScenicBaseMapper scenicBaseMapper;
    private final ScenicPhotoMapper scenicPhotoMapper;

    private final ScenicOtherMapper scenicOtherMapper;

    private final BookedRecordMapper bookedRecordMapper;

    private final TicketTypeMapper ticketTypeMapper;

    private final TimePeriodMapper timePeriodMapper;
    private final TimeConfigMapper timeConfigMapper;

    private final ScenicActivityMapper scenicActivityMapper;

    private final PatternInfoMapper patternInfoMapper;

    private final UserMapper userMapper;

    @Override
    public BaseResponse getScenicRandom() {
        List<ScenicBase> scenicBaseList = scenicBaseMapper.selectScenicRandom();
        return getBaseResponse(scenicBaseList);
    }

    @Override
    public BaseResponse getScenicList() {
        ScenicBaseExample scenicBaseExample = new ScenicBaseExample();
        scenicBaseExample.createCriteria().andIsDeleteEqualTo(true);
        List<ScenicBase> scenicBaseList = scenicBaseMapper.selectByExample(scenicBaseExample);
        return getBaseResponse(scenicBaseList);
    }

    private BaseResponse getBaseResponse(List<ScenicBase> scenicBaseList) {
        List<ScenicBaseRandomVo> scenicBaseRandomVoList = new ArrayList<>();
        for (ScenicBase scenicBase : scenicBaseList) {
            ScenicBaseRandomVo scenicBaseRandomVo = new ScenicBaseRandomVo();
            scenicBaseRandomVo.setScenicBase(scenicBase);
            ScenicPhotoExample scenicPhotoExample = new ScenicPhotoExample();
            scenicPhotoExample.createCriteria().andScenicIdEqualTo(scenicBase.getId());
            List<ScenicPhoto> scenicPhotos = scenicPhotoMapper.selectByExample(scenicPhotoExample);
            if (scenicPhotos.size() > 0) {
                scenicBaseRandomVo.setScenicPhoto(scenicPhotos.get(0).getPhotoUrl());
            }
            scenicBaseRandomVoList.add(scenicBaseRandomVo);
        }
        return BaseResponse.ok(scenicBaseRandomVoList);
    }

    @Override
    public BaseResponse getActive(int id) {
        List<ScenicActivityVo> scenicActivityVoList = new ArrayList<>();
        List<ScenicActivity> scenicActivityList = new ArrayList<>();
        if (id == 0){
            scenicActivityList = scenicActivityMapper.selectActivityRandom();
        } else {
            ScenicActivityExample scenicActivityExample = new ScenicActivityExample();
            scenicActivityExample.createCriteria().andIsDeleteEqualTo(true);
            scenicActivityList = scenicActivityMapper.selectByExample(scenicActivityExample);
        }
        for (ScenicActivity scenicActivity : scenicActivityList){
            ScenicActivityVo scenicActivityVo = new ScenicActivityVo();
            BeanUtils.copyProperties(scenicActivity,scenicActivityVo);
            scenicActivityVoList.add(scenicActivityVo);
        }

        return BaseResponse.ok(scenicActivityVoList);
    }

    @Override
    public BaseResponse getScenicPhoto() {
        List<ScenicPhotoVo> scenicPhotoVoList = new ArrayList<>();
        ScenicPhotoExample scenicPhotoExample = new ScenicPhotoExample();
        List<ScenicPhoto> list = scenicPhotoMapper.selectByExample(scenicPhotoExample);
        Map<Integer, List<ScenicPhoto>> map = list.stream().collect(Collectors.groupingBy(ScenicPhoto::getScenicId));
        for (Map.Entry<Integer, List<ScenicPhoto>> entry : map.entrySet()) {
            ScenicPhotoVo scenicPhotoVo = new ScenicPhotoVo();
            scenicPhotoVo.setScenicPhotoList(entry.getValue());
            scenicPhotoVo.setScenicName(scenicBaseMapper.selectByPrimaryKey(entry.getKey()).getScenicName());
            scenicPhotoVoList.add(scenicPhotoVo);
        }
        return BaseResponse.ok(scenicPhotoVoList);
    }

    @Override
    public BaseResponse getScenicById(Integer id, Date date) {

        if (ObjectUtils.isEmpty(date)){
            // 获取当前日期
            date = new Date();
        }
        // 获取景区其他信息
        ScenicOtherExample scenicOtherExample = new ScenicOtherExample();
        scenicOtherExample.createCriteria().andScenicIdEqualTo(id);
        ScenicOther scenicOther = scenicOtherMapper.selectByExample(scenicOtherExample).get(0);
        // 获取景区门票信息以及可预约时间段以及每个时间段可预约人数、已预约人数
        TicketTypeExample ticketTypeExample = new TicketTypeExample();
        ticketTypeExample.createCriteria().andScenicIdEqualTo(id);
        List<TicketType> ticketTypes = ticketTypeMapper.selectByExample(ticketTypeExample);
        TicketInfo ticketInfo = new TicketInfo();

        // 定义日期格式化器
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ticketInfo.setDate(formatter.format(date));

        TimeConfigExample timeConfigExample = new TimeConfigExample();
        timeConfigExample.createCriteria().andScenicIdEqualTo(id);
        TimeConfig timeConfig = timeConfigMapper.selectByExample(timeConfigExample).get(0);
        for (TicketType ticketType : ticketTypes) {
            ticketInfo.setTicketType(ticketType);
            TimePeriodExample timePeriodExample = new TimePeriodExample();
            timePeriodExample.createCriteria().andScenicIdEqualTo(id);
            List<TimePeriod> timePeriodList = timePeriodMapper.selectByExample(timePeriodExample);
            for (TimePeriod timePeriod :timePeriodList){
                BookedRecordExample bookedRecordExample = new BookedRecordExample();
                bookedRecordExample.createCriteria().andScenicIdEqualTo(id).andTicketTypeIdEqualTo(ticketType.getId()).andPeriodIdEqualTo(timePeriod.getId()).andBookedDateEqualTo(date);
                List<BookedRecord> bookedRecords = bookedRecordMapper.selectByExample(bookedRecordExample);
                BookedVo bookedVo = new BookedVo();
                bookedVo.setTimePeriodId(timePeriod.getId());
                bookedVo.setTimePeriod(timePeriod.getTimePeriod());
                bookedVo.setBookedNum(bookedRecords.size());
                bookedVo.setTotalNum(timeConfig.getPersonNums());
                bookedVo.setRemainNum(timeConfig.getPersonNums() - bookedRecords.size());
                ticketInfo.getBookedVoList().add(bookedVo);
            }
        }
        return BaseResponse.ok(ticketInfo);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class, isolation = Isolation.READ_COMMITTED)
    public BaseResponse addOrder(BookedRecord record) {
        TicketType ticketType = ticketTypeMapper.selectByPrimaryKey(record.getTicketTypeId());
        if (record.getPatternId().isEmpty()){
            return BaseResponse.fail("请选择出行人");
        }
        if (record.getTimePeriod().isEmpty()){
            record.setTimePeriod(timePeriodMapper.selectByPrimaryKey(record.getPeriodId()).getTimePeriod());
        }
        List<String> ids = Arrays.asList(record.getPatternId().split(","));
        if (ids.size() > ticketType.getAllowPerson()){
            return BaseResponse.fail("出行人超过最大限制，请阅读订票规则");
        }
        int judge = bookedRecordMapper.insertSelective(record);
        if (judge > 0){
            return BaseResponse.ok("订票订单生成成功",judge);
        }
        return BaseResponse.fail("订票订单生成失败");
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class, isolation = Isolation.READ_COMMITTED)
    public BaseResponse payOrder(Integer id) {
        BookedRecord bookedRecord = bookedRecordMapper.selectByPrimaryKey(id);
        bookedRecord.setStatus(1);
        int judge = bookedRecordMapper.updateByPrimaryKeySelective(bookedRecord);
        if (judge > 0){
            return BaseResponse.ok("支付成功");
        }
        return BaseResponse.fail("支付失败");
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class, isolation = Isolation.READ_COMMITTED)
    public BaseResponse refundOrder(Integer id) {
        BookedRecord bookedRecord = bookedRecordMapper.selectByPrimaryKey(id);
        bookedRecord.setStatus(2);
        int judge = bookedRecordMapper.updateByPrimaryKeySelective(bookedRecord);
        if (judge > 0){
            return BaseResponse.ok("退票成功");
        }
        return BaseResponse.fail("退票失败");
    }

    @Override
    public BaseResponse getBookedRecord(String mobile) {
        List<BookRecordVo> bookRecordVoList = new ArrayList<>();
        BookedRecordExample bookedRecordExample = new BookedRecordExample();
        bookedRecordExample.createCriteria().andUserMobileEqualTo(mobile);
        bookedRecordExample.setOrderByClause("booked_date desc");
        List<BookedRecord> bookedRecords = bookedRecordMapper.selectByExample(bookedRecordExample);
        for (BookedRecord bookedRecord : bookedRecords){
            BookRecordVo bookRecordVo = new BookRecordVo();
            BeanUtils.copyProperties(bookedRecord, bookRecordVo);
            bookRecordVo.setScenicName(scenicBaseMapper.selectByPrimaryKey(bookedRecord.getScenicId()).getScenicName());
            bookRecordVo.setBookingQrCode(ticketTypeMapper.selectByPrimaryKey(bookedRecord.getTicketTypeId()).getTicketImg());
            List<String> infoIds = Arrays.asList(bookedRecord.getPatternId().split(","));
            List<PatternInfo> patternInfos = new ArrayList<>();
            for (String infoId : infoIds){
                PatternInfo patternInfo = patternInfoMapper.selectByPrimaryKey(Integer.parseInt(infoId));
                patternInfos.add(patternInfo);
            }
            bookRecordVo.setPatternInfoList(patternInfos);
            bookRecordVoList.add(bookRecordVo);
        }
        return BaseResponse.ok(bookRecordVoList);
    }

    @Override
    public BaseResponse addPartner(PatternInfo info) {
        int judge = patternInfoMapper.insertSelective(info);
        if (judge > 0){
            return BaseResponse.ok("添加成功");
        }
        return BaseResponse.fail("添加失败");
    }

    @Override
    public BaseResponse editPartner(PatternInfo info) {
        int judge = patternInfoMapper.updateByPrimaryKeySelective(info);
        if (judge > 0){
            return BaseResponse.ok("修改成功");
        }
        return BaseResponse.fail("修改失败");
    }

    @Override
    public BaseResponse deletePartner(Integer id) {
        PatternInfo info = patternInfoMapper.selectByPrimaryKey(id);
        info.setIsDelete(false);
        int judge = patternInfoMapper.updateByPrimaryKeySelective(info);
        if (judge > 0){
            return BaseResponse.ok("删除成功");
        }
        return BaseResponse.fail("删除失败");
    }

    @Override
    public BaseResponse getPartnerByUserId(String mobile) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andMobileEqualTo(mobile);
        User user = userMapper.selectByExample(userExample).get(0);
        PatternInfoExample patternInfoExample = new PatternInfoExample();
        patternInfoExample.createCriteria().andUserIdEqualTo(user.getId()).andIsDeleteEqualTo(true);
        List<PatternInfo> patternInfos = patternInfoMapper.selectByExample(patternInfoExample);
        return BaseResponse.ok(patternInfos);
    }


}
